﻿using AutoMapper;
using Newtonsoft.Json;
using Oplug.EntityFramework.RossLive;
using Oplug.CoolTower.Attributes;
using Oplug.CoolTower.Filters;
using Oplug.Services;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace Oplug.CoolTower
{
    public partial class FormPowers : Form
    {
        private DTO.SysConfig cfg;
        private Utilities Utility;
        private List<FormMethods> MethodLists;
        private List<RossUsers> UserList;
        public FormPowers()
        {
            InitializeComponent();
        }
        [Description("权限设置窗体加载")]
        private void FormPowers_Load(object sender, EventArgs e)
        {
            Utility = new Utilities();
            UserList = new List<RossUsers>();
            cfg = Utility.GetSysCfg();
            LoadUsers(DgvUsers);
            LoadPowers();
            this.Text += "-" + Utilities.CompName;
            using (PowerService Serv = new PowerService(cfg.DBConn))
            {
                MethodLists = Serv.formMethods.GetAllList();
            }
        }

        public async void LoadPowers()
        {
            PowerService RLVPowers = new PowerService(cfg.DBConn);
            var PowerList = await RLVPowers.repository.GetAllListAsync(o => o.Client == Application.ProductName);
            BindTreeView(PowerList, 0, treeViewM);            
            RLVPowers.Dispose();
        }

        public async void LoadUsers(DataGridView dgv)
        {
            UserService Serv = new UserService(cfg.DBConn);            
            if (string.IsNullOrEmpty(toolBoxUser.Text))
            {
                UserList = await Serv.repository.GetAllListAsync();
            }
            else
            {
                UserList = await Serv.repository.GetAllListAsync(o => o.UserID.Contains(toolBoxUser.Text) || o.UserName.Contains(toolBoxUser.Text));
            }
            dgv.DataSource = UserList.Select(o => new { o.ID, o.UserID, o.UserName }).ToList(); 
            dgv.Columns[0].Visible = false;
            dgv.Columns[1].HeaderCell.Value = "用户编号";
            dgv.Columns[2].HeaderCell.Value = "用户名";

            listBoxAllowUsers.DataSource = UserList.ToList();
            listBoxAllowUsers.DisplayMember = "UserID";
            listBoxAllowUsers.ValueMember = "UserID";

            Serv.Dispose();
        }

        private void BindTreeView(List<RossPowers> Rows, int parentID, TreeView tree)
        {
            try
            {
                var root = Rows.Where(o => o.ParentID == parentID).FirstOrDefault();
                if (root != null)
                {
                    TreeNode rootNode = new TreeNode();
                    rootNode.Tag = root.ID;
                    rootNode.Text = root.PowerName;
                    rootNode.ToolTipText = root.PowerIndex;
                    tree.Nodes.Add(rootNode);

                    var childs = Rows.Where(o => o.ParentID == root.ID).ToList();
                    foreach (var item in childs)
                    {
                        TreeNode node = new TreeNode();
                        node.Tag = item.ID;
                        node.Text = item.PowerName;
                        node.ToolTipText = item.PowerIndex;
                        rootNode.Nodes.Add(node);
                        BindTreeViewChild(Rows, node);
                    }

                    tree.Nodes[0].ExpandAll();
                    tree.SelectedNode = tree.Nodes[0];
                }
            }
            catch (Exception err)
            {
                Utilities.Message(err.Message, InfoType.Error);
            }
        }
        private void BindTreeViewChild(List<RossPowers> Rows, TreeNode fNode)
        {
            var childs = Rows.Where(o => o.ParentID == int.Parse(fNode.Tag.ToString())).ToList();
            if (childs.Count == 0)
            {
                return;
            }

            foreach (var item in childs)
            {
                TreeNode node = new TreeNode();
                node.Tag = item.ID;
                node.Text = item.PowerName;
                node.ToolTipText = item.PowerIndex;
                fNode.Nodes.Add(node);
                //递归
                BindTreeViewChild(Rows, node);
            }
        }

        private void DgvUsers_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            using (UserService RLD = new UserService(cfg.DBConn))
            {
                int CurrUserID = Utilities.CInt(DgvUsers.CurrentRow.Cells["ID"].Value);
                var User = RLD.repository.Get(CurrUserID);
                if (User != null)
                {
                    User.Powers = User.Powers == null ? "[]" : User.Powers;
                    var userPower = JsonConvert.DeserializeObject<List<DTO.UserPowerSetting>>(User.Powers);
                    if (userPower != null)
                    {
                        var datas = userPower.Select(o => o.PowerIndex);
                        ChkTreeVNode(datas, treeViewM.Nodes[0]);
                    }
                }
            }
        }
        private void ChkTreeVNode(IEnumerable<string> powers, TreeNode fatn, bool chkAll = false)
        {
            foreach (TreeNode tn in fatn.Nodes)
            {
                if (!chkAll)
                {
                    if (powers!=null && powers.Contains(tn.ToolTipText) && !string.IsNullOrEmpty(tn.ToolTipText))
                        tn.Checked = true;
                    else
                        tn.Checked = false;
                }
                else
                    tn.Checked = ChkAll.Checked;
                ChkTreeVNode(powers, tn, chkAll);
            }
        }

        private void ChkAll_CheckedChanged(object sender, EventArgs e)
        {
            ChkTreeVNode(null, treeViewM.Nodes[0], true);
        }

        [Description("保存用户菜单权限")]
        private void toolBtn_Save_Click(object sender, EventArgs e)
        {
            if (!MethodFilters.IsDeny(MethodBase.GetCurrentMethod().Name, Name, cfg.DBConn))
            {
                int CurrUserID = Utilities.CInt(DgvUsers.CurrentRow.Cells["ID"].Value);
                if (CurrUserID > 0)
                {
                    using (UserService RLD = new UserService(cfg.DBConn))
                    {
                        List<DTO.UserPowerSetting> PowerSelects = new List<DTO.UserPowerSetting>();
                        TreeNode Root = treeViewM.Nodes[0];
                        PowerSelects.Add(new DTO.UserPowerSetting()
                        {
                            Client = Application.ProductName,
                            ID = Utilities.CInt(Root.Tag),
                            PowerIndex = Root.ToolTipText,
                            PowerName = Root.Text
                        });
                        GetChkTreeNode(Root, PowerSelects);
                        var user = RLD.repository.Get(CurrUserID);

                        List<DTO.UserPowerSetting> currPower = null;
                        try
                        {
                            currPower = new List<DTO.UserPowerSetting>();
                            currPower = JsonConvert.DeserializeObject<List<DTO.UserPowerSetting>>(user.Powers);
                            currPower = currPower.Where(o => o.Client != Application.ProductName).ToList();
                        }
                        catch { }
                        if (currPower != null)
                            PowerSelects = PowerSelects.Union(currPower).ToList();
                        string powers = JsonConvert.SerializeObject(PowerSelects);

                        user.Powers = powers;
                        RLD.repository.Update(user);
                        Utilities.Message("权限设置成功", InfoType.Information);
                    }
                }
                else
                {
                    Utilities.Message("请选择一个用户！", InfoType.Warning);
                }
            }
        }
        private void GetChkTreeNode(TreeNode parentNode, List<DTO.UserPowerSetting> powers)
        {
            foreach (TreeNode node in parentNode.Nodes)
            {
                if (node.Checked)
                    powers.Add(new DTO.UserPowerSetting() {
                        Client = Application.ProductName,
                        ID = Utilities.CInt(node.Tag),
                        PowerIndex = node.ToolTipText,
                        PowerName = node.Text
                    });
                GetChkTreeNode(node, powers);
            }
        }

        [Description("搜索用户")]
        private void toolBtn_Search_Click(object sender, EventArgs e)
        {
            if (!MethodFilters.IsDeny(MethodBase.GetCurrentMethod().Name, Name, cfg.DBConn))
                LoadUsers(DgvUsers);
        }

        
        private void tabControlM_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabControlM.SelectedIndex == 1)
            {
                dgvS.DataSource = MethodLists.Select(o => new { o.ID, o.MethodName, o.MethodDesc }).ToList();
                comboBoxForms.ComboBox.DataSource = MethodLists.Select(o => new { o.FormName }).Distinct().ToList();
                comboBoxForms.ComboBox.DisplayMember = "FormName";
                comboBoxForms.ComboBox.ValueMember = "FormName";

                string[] headerArr = ("编号,方法索引,方法名").Split(',');
                for (int i = 0; i < headerArr.Length; i++)
                {
                    dgvS.Columns[i].HeaderText = headerArr[i];                    
                }
                dgvS.Columns[0].Width = 60;
            }
            toolStripM.Enabled = tabControlM.SelectedIndex == 0;
        }

        private void comboBoxForms_SelectedIndexChanged(object sender, EventArgs e)
        {
            string val = comboBoxForms.ComboBox.SelectedValue.ToString();
            var lists = MethodLists.Where(o => o.FormName == o.MethodType && o.FormName == val).ToList();
            dgvS.DataSource = lists.Where(o=>!string.IsNullOrEmpty(o.MethodDesc)).Select(o => new { o.ID, o.MethodName, o.MethodDesc }).ToList();
        }

        private void buttonGetmethod_Click(object sender, EventArgs e)
        {
            var lists = Utility.GetAllMethods().Where(o => o.FormName == o.MethodType).ToList();
            using (PowerService Serv = new PowerService(cfg.DBConn))
            {
                foreach(var item in lists)
                {
                    var obj = Serv.formMethods.GetAllList(o => o.FormName == item.FormName && o.MethodName == item.MethodName).FirstOrDefault();
                    if (obj == null)
                    {
                        FormMethods model = Mapper.Map<FormMethods>(item);
                        Serv.formMethods.Insert(model);
                    }
                    else
                    {
                        obj.MethodDesc = item.MethodDesc;
                        obj.MethodType = item.MethodType;
                        Serv.formMethods.Update(obj);
                    }
                }
                var mlists = Serv.formMethods.GetAllList(o => string.IsNullOrEmpty(o.MethodDesc));
                foreach(var obj in mlists)
                {
                    Serv.formMethods.Delete(obj);
                }
                MethodLists = Serv.formMethods.GetAllList();
            }
        }

        private void dgvS_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            using (PowerService Serv = new PowerService(cfg.DBConn))
            {
                int ID = Utilities.CInt(dgvS.CurrentRow.Cells["ID"].Value);
                var obj = Serv.formMethods.Get(ID);
                if (obj != null && obj.DenyUsers != null)
                {
                    string[] users = obj.DenyUsers.Split(',');
                    listBoxDenyUsers.DataSource = users;
                    listBoxAllowUsers.DataSource = UserList.Where(o=>!users.Contains(o.UserID)).ToList();
                }
                else
                {
                    listBoxDenyUsers.DataSource = null;
                    listBoxAllowUsers.DataSource = UserList.ToList();
                }
            }
        }

        private void buttonSaveM_Click(object sender, EventArgs e)
        {
            using (PowerService Serv = new PowerService(cfg.DBConn))
            {
                int ID = Utilities.CInt(dgvS.CurrentRow.Cells["ID"].Value);
                var obj = Serv.formMethods.Get(ID);
                if (obj != null)
                {
                    string[] arr = listBoxDenyUsers.Items.OfType<string>().ToArray();
                    obj.DenyUsers = string.Join(",", arr);
                    Serv.formMethods.Update(obj);
                    Utilities.Message("更新成功！");
                }
            }
        }

        private void buttonPut_Click(object sender, EventArgs e)
        {
            List<string> listDeny = listBoxDenyUsers.Items.OfType<string>().ToList();
            
            foreach (RossUsers item in listBoxAllowUsers.SelectedItems)
            {
                if (!listDeny.Contains(item.UserID))
                    listDeny.Add(item.UserID);
            }
            listBoxDenyUsers.DataSource = listDeny.ToArray();

            ReBindAllowUser(listDeny.ToArray());
        }

        private void buttonDel_Click(object sender, EventArgs e)
        {
            string[] strArray = listBoxDenyUsers.Items.OfType<string>().ToArray();

            List<string> list = new List<string>();
            foreach (string s in strArray)
            {
                if (s != listBoxDenyUsers.SelectedValue.ToString())
                {
                    list.Add(s);
                }
            }
            strArray = list.ToArray();
            listBoxDenyUsers.DataSource = strArray;

            ReBindAllowUser(strArray);
        }

        private void ReBindAllowUser(string[] listDeny)
        {
            List<RossUsers> listAllowNew = UserList.Where(o => !listDeny.Contains(o.UserID)).ToList();
            listBoxAllowUsers.DataSource = null;
            listBoxAllowUsers.DataSource = listAllowNew;
            listBoxAllowUsers.DisplayMember = "UserID";
            listBoxAllowUsers.ValueMember = "UserID";
        }
    }
}
